﻿@using System.ComponentModel.DataAnnotations
@using System.Text.Json
@layout StudentLayout
@inject StudentClient Http
@inject NavigationManager Navigation

@if (hasError){
    <Alert Type="@AlertType.Error"
       Message="错误"
       Description="@errorMessage"
       ShowIcon="true" 
       Closable />
}
@if (loading)
{
    <p>Loading...</p>
}
else 
{
    <Breadcrumb Style="margin:2vh;" Separator=">">
		<BreadcrumbItem Href="/login/student">学生登录</BreadcrumbItem>
		<BreadcrumbItem Href="/StudentProfile">检查信息</BreadcrumbItem>
		<BreadcrumbItem>修改并提交信息</BreadcrumbItem>
	</Breadcrumb>
    <Form Model="@model"
          Loading="@isFormLoading"
          OnFinish="OnFinish"
          Size="@AntSizeLDSType.Large"
          LabelColSpan="3"
          WrapperColSpan="16"
          Style="padding-bottom:3vh;margin:0 auto;">
        <FormItem WrapperColOffset="0" WrapperColSpan="16" Style="margin:3vh;">
            <h2>寝室信息核对</h2>
            <p>请核对以下信息，如有错误请修改，校外住宿请勾选复选框并填写详细地址。</p>
        </FormItem>
        <FormItem Label="校区">
            <Select DataSource="@_regionList"
                @bind-Value="@context.Region"
                ValueName="@nameof(Region.RegionName)"
                LabelName="@nameof(Region.RegionName)"
                Placeholder="选择校区"
                OnSelectedItemChanged="(region) => {_areaList = region.Areas; 
                            model.Building = model.Floor = model.Room = model.Bed = string.Empty;
                            _buildingList = null; _floorList = null; _roomList = null; _bedList = null; }">
            </Select>
        </FormItem>
        <FormItem Label="园区">
            <Select DataSource="@_areaList"
                @bind-Value="@context.Area"
                ValueName="@nameof(Area.AreaName)"
                LabelName="@nameof(Area.AreaName)"
                Placeholder="选择园区"
                OnSelectedItemChanged="(area) => {_buildingList = area.Buildings;
                            model.Floor = model.Room = model.Bed = string.Empty;
                            _floorList = null; _roomList = null; _bedList = null; }">
            </Select>
        </FormItem>
        <FormItem Label="楼栋">
            <Select DataSource="@_buildingList"
                @bind-Value="@context.Building"
                ValueName="@nameof(Building.BuildingName)"
                LabelName="@nameof(Building.BuildingName)"
                Placeholder="选择楼栋"
                OnSelectedItemChanged="(building) => {_floorList = building.Floor;
                            model.Room = model.Bed = string.Empty; _roomList = null; _bedList = null;}">
            </Select>
        </FormItem>
        <FormItem Label="楼层">
            <Select DataSource="@_floorList"
                @bind-Value="@context.Floor"
                ValueName="@nameof(Floor.FloorName)"
                LabelName="@nameof(Floor.FloorName)"
                Placeholder="选择楼层"
                OnSelectedItemChanged="(floor) => {_roomList = floor.Rooms;model.Bed = string.Empty; _bedList = null;}">
            </Select>
        </FormItem>
        <FormItem Label="房间">
            <Select DataSource="@_roomList"
                @bind-Value="@context.Room"
                ValueName="@nameof(Room.RoomNum)"
                LabelName="@nameof(Room.RoomNum)"
                Placeholder="选择房间"
                OnSelectedItemChanged="(floor) => _bedList = Enumerable.Range(1, floor.BedCount).Select(x=>x.ToString())">
            </Select>
        </FormItem>
        <FormItem Label="床位">
            <Select DataSource="@_bedList"
                @bind-Value="@context.Bed"
                Placeholder="选择床位">
            </Select>
        </FormItem>
        <FormItem Label="校外住宿">
            <Switch @bind-Value="@isOutSchool" OnClick="() => context.Address = string.Empty"/>
        </FormItem>
        <FormItem Label="校外住宿地址">
            <Select DataSource="@_provinceList"
                Disabled="@(!isOutSchool)"
                @bind-Value="@context.Provice"
                ValueName="@nameof(CNRegion.Name)"
                LabelName="@nameof(CNRegion.Name)"
                Placeholder="选择省份"
                OnSelectedItemChanged="async (region) => {_cityList.Clear(); _cityList.AddRange(await this.Http.GetRegionChildren(region.Id)); 
                            model.Village = model.Street = null;
                            _villageList.Clear(); _streetList.Clear(); }">
            </Select>
            <Select DataSource="@_cityList"
                Disabled="@(!isOutSchool)"
                @bind-Value="@context.City"
                ValueName="@nameof(CNRegion.Name)"
                LabelName="@nameof(CNRegion.Name)"
                Placeholder="选择城市"
                OnSelectedItemChanged="async (region) => {_villageList.Clear(); _villageList.AddRange(await this.Http.GetRegionChildren(region.Id)); 
                            model.Street = null;
                            _streetList.Clear(); }">
            </Select>
            <Select DataSource="@_villageList"
                Disabled="@(!isOutSchool)"
                @bind-Value="@context.Village"
                ValueName="@nameof(CNRegion.Name)"
                LabelName="@nameof(CNRegion.Name)"
                Placeholder="选择区"
                OnSelectedItemChanged="async (region) =>{_streetList.Clear(); _streetList.AddRange(await this.Http.GetRegionChildren(region.Id));}">
            </Select>
            <Select DataSource="@_streetList"
                Disabled="@(!isOutSchool)"
                @bind-Value="@context.Street"
                ValueName="@nameof(CNRegion.Name)"
                LabelName="@nameof(CNRegion.Name)"
                Placeholder="选择街道">
            </Select>
            <Input @bind-Value="@context.Address"
                   Disabled="@(!isOutSchool)"
                   Placeholder="详细地址"/>
        </FormItem>
        <div style="width:100%;display:flex;flex-direction:column;align-items:center;">
            <Button Size="@ButtonSize.Large" Type="@ButtonType.Primary" HtmlType="submit" Style="margin:0 auto">
                核对无误，确认提交
            </Button>
        </div>
    </Form>
}

@code {
    [Parameter]
    public bool ForceConfirm { get; set; } = false;
    [Parameter]
    public Bed? Doom { get; set; } = null!;

    private bool loading = true;
    private DoomMeta? DoomMetas;

    private IEnumerable<Region>? _regionList;
    private IEnumerable<Area>? _areaList;
    private IEnumerable<Building>? _buildingList;
    private IEnumerable<Floor>? _floorList;
    private IEnumerable<Room>? _roomList;
    private IEnumerable<string>? _bedList;

    private List<CNRegion> _provinceList = new();
    private List<CNRegion> _cityList = new();
    private List<CNRegion> _villageList = new();
    private List<CNRegion> _streetList = new();


    private bool isOutSchool = false;
    private bool isFormLoading = false;
    private bool hasError = false;
    private string errorMessage = "";

    private Model model = new();

    protected class Model
    {
        [Required(ErrorMessage = "必填字段")]
        public string? Region { get; set; }
        [Required(ErrorMessage = "必填字段")]
        public string? Area { get; set; }
        [Required(ErrorMessage = "必填字段")]
        public string? Building { get; set; }
        [Required(ErrorMessage = "必填字段")]
        public string? Floor { get; set; }
        [Required(ErrorMessage = "必填字段")]
        public string? Room { get; set; }
        [Required(ErrorMessage = "必填字段")]
        public string? Bed { get; set; }
        [MaxLength(255)]
        public string? Address { get; set; }
        public string? Provice { get; set; }
        public string? City { get; set; }
        public string? Village { get; set; }
        public string? Street { get; set; }
    }

    private async Task OnFinish(EditContext editContext)
    {
        if(isOutSchool && 
            (string.IsNullOrWhiteSpace(model.Address) || model.Provice is null || model.City is null || model.Village is null || model.Street is null))
        {
            SetError("勾选校外住宿后请填写相应信息");
            return;
        }
        isFormLoading = true;
        var success = await Http.UpdateDoom(new UpdateDoomRequest(model.Region!, model.Area!,
                            model.Building!, int.Parse(model.Floor!), model.Room!, int.Parse(model.Bed!), $"{model.Provice}{model.City}{model.Village}{model.Street}{model.Address}", ForceConfirm));
        isFormLoading = false;
        if (!success) 
        {
            SetError("提交失败，请稍后重试");
            return;
        }
        Navigation.NavigateTo("/StudentProfile");
    }

    protected override async Task OnInitializedAsync()
    {
        DoomMetas = await Http.GetDoomMeta();

        _provinceList = (await Http.GetProvinces()).ToList();

        _regionList = DoomMetas.Regions;
        _areaList = _regionList.Where(x => x.RegionName == Doom?.Region).SingleOrDefault()?.Areas;
        _buildingList = _areaList?.Where(x => x.AreaName == Doom?.Area).SingleOrDefault()?.Buildings;
        _floorList = _buildingList?.Where(x => x.BuildingName == Doom?.Building).SingleOrDefault()?.Floor;
        _roomList = _floorList?.Where(x => x.FloorName == Doom?.Floor.ToString()).SingleOrDefault()?.Rooms;
        var room = _roomList?.Where(x => x.RoomNum == Doom?.RoomNumber).SingleOrDefault();
        if (room is not null)
        {
            _bedList = Enumerable.Range(1, room.BedCount).Select(x => x.ToString());
        }

        model.Region = Doom?.Region;
        model.Area = Doom?.Area;
        model.Building = Doom?.Building;
        model.Floor = Doom?.Floor.ToString();
        model.Room = Doom?.RoomNumber;
        model.Bed = (Doom?.BedNumber == 0 ? 1 : Doom?.BedNumber).ToString();

        loading = false;
    }

    private void Navigate()
    {
        Navigation.NavigateTo("/");
    }
        
    private void SetError(string msg)
    {
        hasError = true;
        errorMessage = msg;
    }
}